﻿using System;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Win32;

namespace SHomeWorkshop.LunarPresentation.Dialogs
{
    /// <summary>
    /// DocBackgroundImageDlg.xaml 的交互逻辑
    /// </summary>
    public partial class DocBackgroundImageDlg : Window
    {
        public DocBackgroundImageDlg(Editor editor)
        {
            InitializeComponent();

            this.Owner = Globals.MainWindow;
            this.editor = editor;

            Type type = typeof(Brushes);
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo pi in properties)
            {
                BrushItem bi1 = new BrushItem(pi.GetValue(null, null) as Brush, pi.Name);
                cboxBackgroundBrushes.Items.Add(bi1);

                BrushItem bi2 = new BrushItem(pi.GetValue(null, null) as Brush, pi.Name);
                cboxForegroundBrushes.Items.Add(bi2);

                BrushItem bi3 = new BrushItem(pi.GetValue(null, null) as Brush, pi.Name);
                cboxSelBox1Brushes.Items.Add(bi3);

                BrushItem bi4 = new BrushItem(pi.GetValue(null, null) as Brush, pi.Name);
                cboxSelBox2Brushes.Items.Add(bi4);
            }

            if (editor != null)
            {
                tbForegroundSample.Foreground = editor.DefaultForeground;

                rect11.Fill = rect12.Fill = rect13.Fill = rect14.Fill = rect1.Stroke = editor.ExSelectionAdornerBrush;
                rect21.Fill = rect22.Fill = rect23.Fill = rect24.Fill = rect2.Stroke = editor.SubPanelSelectionAdornerBrush;

                //如果背景色是纯色，读入背景色，如果不是纯色，读入图像背景。

                ImageBrush editorImgBrush = editor.BaseScrolledViewer.Background as ImageBrush;
                if (editorImgBrush != null)
                {
                    rbtnFillWithImageBrush.IsChecked = true;
                    ImageBrush newImageBrush = new ImageBrush(editorImgBrush.ImageSource)
                    {
                        TileMode = editorImgBrush.TileMode,
                        Viewport = editorImgBrush.Viewport,
                        ViewportUnits = editorImgBrush.ViewportUnits,
                        Stretch = editorImgBrush.Stretch,
                    };

                    switch (editorImgBrush.TileMode)
                    {
                        case TileMode.FlipX:
                            {
                                rbtnFlipX.IsChecked = true; break;
                            }
                        case TileMode.FlipY:
                            {
                                rbtnFlipY.IsChecked = true; break;
                            }
                        case TileMode.FlipXY:
                            {
                                rbtnFlipXY.IsChecked = true; break;
                            }
                        case TileMode.Tile:
                            {
                                rbtnTileWithoutFlip.IsChecked = true; break;
                            }
                        default:
                            {
                                rbtnFlipNone.IsChecked = true; break;
                            }
                    }

                    rectanglePreview.Fill = newImageBrush;

                    btnResetBackImgBrush.Tag = newImageBrush;//以便恢复。

                    cboxBackgroundBrushes.IsEnabled = false;

                    dPanelOfImagePath.IsEnabled = true;
                    gpOfImageFlipType.IsEnabled = true;
                }
                else
                {
                    rbtnFlipXY.IsChecked = true;//默认为水平、垂直翻转并平铺。

                    rbtnFillWithSolidBrush.IsChecked = true;

                    cboxBackgroundBrushes.IsEnabled = true;

                    dPanelOfImagePath.IsEnabled = false;
                    gpOfImageFlipType.IsEnabled = false;

                    rectanglePreview.Fill = editor.BaseScrolledViewer.Background;

                    btnResetBackImgBrush.Tag = null;
                }

                //为避免不必要的事件，直到此时才挂接。
                cboxForegroundBrushes.SelectionChanged += new SelectionChangedEventHandler(cboxForegroundBrushes_SelectionChanged);
                rbtnFillWithSolidBrush.Checked += new RoutedEventHandler(rbtnFillWithSolidBrush_Checked);
                cboxBackgroundBrushes.SelectionChanged += new SelectionChangedEventHandler(cboxBackgroundBrushes_SelectionChanged);
                rbtnFillWithImageBrush.Checked += new RoutedEventHandler(rbtnFillWithImageBrush_Checked);

                rbtnFlipX.Checked += new RoutedEventHandler(rbtnFlipX_Checked);
                rbtnFlipY.Checked += new RoutedEventHandler(rbtnFlipY_Checked);
                rbtnFlipXY.Checked += new RoutedEventHandler(rbtnFlipXY_Checked);
                rbtnTileWithoutFlip.Checked += new RoutedEventHandler(rbtnTileWithoutFlip_Checked);
                rbtnFlipNone.Checked += new RoutedEventHandler(rbtnFlipNone_Checked);

                cboxSelBox1Brushes.SelectionChanged += new SelectionChangedEventHandler(cboxSelBox1Brushes_SelectionChanged);
                cboxSelBox2Brushes.SelectionChanged += new SelectionChangedEventHandler(cboxSelBox2Brushes_SelectionChanged);
            }
        }

        void rbtnFlipNone_Checked(object sender, RoutedEventArgs e)
        {
            ImageBrush ibsh = rectanglePreview.Fill as ImageBrush;
            if (ibsh != null)
            {
                ibsh.TileMode = TileMode.None;
            }
        }

        void rbtnTileWithoutFlip_Checked(object sender, RoutedEventArgs e)
        {
            ImageBrush ibsh = rectanglePreview.Fill as ImageBrush;
            if (ibsh != null)
            {
                ibsh.TileMode = TileMode.Tile;
            }
        }

        void rbtnFlipXY_Checked(object sender, RoutedEventArgs e)
        {
            ImageBrush ibsh = rectanglePreview.Fill as ImageBrush;
            if (ibsh != null)
            {
                ibsh.TileMode = TileMode.FlipXY;
            }
        }

        void rbtnFlipY_Checked(object sender, RoutedEventArgs e)
        {
            ImageBrush ibsh = rectanglePreview.Fill as ImageBrush;
            if (ibsh != null)
            {
                ibsh.TileMode = TileMode.FlipY;
            }
        }

        void rbtnFlipX_Checked(object sender, RoutedEventArgs e)
        {
            ImageBrush ibsh = rectanglePreview.Fill as ImageBrush;
            if (ibsh != null)
            {
                ibsh.TileMode = TileMode.FlipX;
            }
        }

        private Editor editor;

        private void rbtnFillWithSolidBrush_Checked(object sender, RoutedEventArgs e)
        {
            if (dPanelOfImagePath != null) dPanelOfImagePath.IsEnabled = false;
            if (gpOfImageFlipType != null) gpOfImageFlipType.IsEnabled = false;
            if (cboxBackgroundBrushes != null) cboxBackgroundBrushes.IsEnabled = true;
        }

        private void rbtnFillWithImageBrush_Checked(object sender, RoutedEventArgs e)
        {
            if (dPanelOfImagePath != null) dPanelOfImagePath.IsEnabled = true;
            if (gpOfImageFlipType != null) gpOfImageFlipType.IsEnabled = true;
            if (cboxBackgroundBrushes != null) cboxBackgroundBrushes.IsEnabled = false;
        }

        class BrushItem : ComboBoxItem
        {
            static Thickness ItemMargin = new Thickness(10, 0, 10, 0);

            public BrushItem(Brush bsh, string bshName)
            {
                Bsh = bsh;
                BrushName = bshName;

                StackPanel sPanel = new StackPanel() { Orientation = Orientation.Horizontal };
                this.Content = sPanel;

                sPanel.Children.Add(new Rectangle() { Width = 10, Height = 10, Fill = bsh });
                sPanel.Children.Add(new TextBlock() { Text = ToString(), Margin = ItemMargin });
            }

            public Brush Bsh { get; set; }

            public string BrushName { get; set; }

            public override string ToString()
            {
                return BrushName;
            }
        }

        private void cboxBackgroundBrushes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            BrushItem bi = cboxBackgroundBrushes.SelectedItem as BrushItem;
            if (bi != null)
            {
                rectanglePreview.Fill = bi.Bsh;
            }
            else
            {
                if (editor != null)
                {
                    rectanglePreview.Fill = editor.DefaultBackground;
                }
            }
        }

        private void cboxForegroundBrushes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            BrushItem bi = cboxForegroundBrushes.SelectedItem as BrushItem;
            if (bi != null)
            {
                tbForegroundSample.Foreground = bi.Bsh;
            }
            else
            {
                if (editor != null)
                {
                    tbForegroundSample.Foreground = editor.DefaultForeground;
                }
            }
        }

        private void cboxSelBox1Brushes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //普通公式的选取框色
            BrushItem bi = cboxSelBox1Brushes.SelectedItem as BrushItem;

            if (bi != null)
            {
                Brush bsh = bi.Bsh;

                rect1.Stroke = bsh;
                rect11.Fill = bsh;
                rect12.Fill = bsh;
                rect13.Fill = bsh;
                rect14.Fill = bsh;
            }
            else
            {
                if (editor != null)
                {
                    Brush bsh = editor.ExSelectionAdornerBrush;

                    rect1.Stroke = bsh;
                    rect11.Fill = bsh;
                    rect12.Fill = bsh;
                    rect13.Fill = bsh;
                    rect14.Fill = bsh;
                }
            }
        }

        private void cboxSelBox2Brushes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //子面板的选取框色
            BrushItem bi = cboxSelBox2Brushes.SelectedItem as BrushItem;

            if (bi != null)
            {
                Brush bsh = bi.Bsh;

                rect2.Stroke = bsh;
                rect21.Fill = bsh;
                rect22.Fill = bsh;
                rect23.Fill = bsh;
                rect24.Fill = bsh;
            }
            else
            {
                if (editor != null)
                {
                    Brush bsh = editor.SubPanelSelectionAdornerBrush;

                    rect2.Stroke = bsh;
                    rect21.Fill = bsh;
                    rect22.Fill = bsh;
                    rect23.Fill = bsh;
                    rect24.Fill = bsh;
                }
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
        }

        private void btnBrowseImageFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = false;
            ofd.Title = Globals.appName + "——请为图片框选择需要的图片：";
            ofd.Filter = "支持的所有图片格式(*.bmp;*.gif;*.jpg;*.jpeg;*.png;*.tiff)|*.bmp;*.gif;*.jpg;*.jpeg;*.png;*.tiff|" +
                "PNG或JPEG图片(*.png;*.jpg;*.jpeg)|*.png;*.jpg;*.jpeg|" +
                "联合图像专家组格式(*.jpg;*.jpeg)|*.jpg;*.jpeg|" +
                "图形交换格式(*.gif)|*.gif|" +
                "W3C 可移植网络图形(*png)|*png|" +
                "标题图像文件(*.tiff)|*.tiff";

            if (ofd.ShowDialog() != true) return;

            string filename = ofd.FileName;

            System.IO.FileInfo fileInfo = new FileInfo(filename);

            if (fileInfo.Exists == false)
            {
                System.Windows.MessageBox.Show("发生意外，指定的图片文件不存在！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (fileInfo.Length <= 1024000)//将图片限制在1MB以内
            {
                System.Drawing.Image fileImg = System.Drawing.Image.FromFile(filename);
                using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
                {
                    try
                    {
                        if (fileInfo.Extension.ToLower() == ".png")
                        {
                            fileImg.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                        }
                        else if (fileInfo.Extension.ToLower() == ".jpg" || fileInfo.Extension.ToLower() == ".jpeg")
                        {
                            fileImg.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
                        }
                        else if (fileInfo.Extension.ToLower() == ".gif")
                        {
                            fileImg.Save(stream, System.Drawing.Imaging.ImageFormat.Gif);
                        }
                        else if (fileInfo.Extension.ToLower() == ".tiff")
                        {
                            fileImg.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff);
                        }
                        else if (fileInfo.Extension.ToLower() == ".bmp")
                        {
                            fileImg.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
                        }
                        else
                        {
                            return;//不能识别的文件格式。
                        }

                        byte[] b = stream.GetBuffer();
                        string imgDataText = Convert.ToBase64String(b);

                        ImageBrush newLoadedImageBrush = new ImageBrush()
                        {
                            ImageSource = new BitmapImage(new Uri(filename, UriKind.Relative)),
                            ViewportUnits = System.Windows.Media.BrushMappingMode.Absolute,
                            Viewport = new Rect(0, 0, fileImg.Width, fileImg.Height),
                        };

                        if (rbtnFlipX.IsChecked == true)
                        {
                            newLoadedImageBrush.TileMode = TileMode.FlipX;
                        }
                        if (rbtnFlipY.IsChecked == true)
                        {
                            newLoadedImageBrush.TileMode = TileMode.FlipY;
                        }
                        if (rbtnFlipXY.IsChecked == true)
                        {
                            newLoadedImageBrush.TileMode = TileMode.FlipXY;
                        }
                        if (rbtnTileWithoutFlip.IsChecked == true)
                        {
                            newLoadedImageBrush.TileMode = TileMode.Tile;
                        }
                        if (rbtnFlipNone.IsChecked == true)
                        {
                            newLoadedImageBrush.TileMode = TileMode.None;
                        }

                        rectanglePreview.Fill = newLoadedImageBrush;
                        tbxImageFilePath.Tag = imgDataText;
                        tbxImageFilePath.Text = filename;
                    }
                    catch (System.Runtime.InteropServices.ExternalException ex)
                    {
                        Dialogs.LunarMsgBox.MsgBoxShow(
                            Globals.appName,
                            "该图片文件后缀名有问题，或图片被损坏。",
                            "该图像以错误的图像格式后缀名保存！\r\n" + ex.Message,
                            ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                    }
                }
            }
            else
            {
                Dialogs.LunarMsgBox.MsgBoxShow(
                    Globals.appName,
                    "所选择的图片文件过大！",
                    "为防止文档体积过分庞大，本图片框只支持文件尺寸在 1MB 以下的图片！",
                    "请将图片加工一下或另选一张图片。",
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
        }

        /// <summary>
        /// 图像背景复位按钮。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnResetBackImgBrush_Click(object sender, RoutedEventArgs e)
        {
            if (btnResetBackImgBrush.Tag == null)
            {
                MessageBox.Show("此文档的背景不是图片，不能复位。", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            ImageBrush ibsh = btnResetBackImgBrush.Tag as ImageBrush;
            if (ibsh != null)
            {
                rectanglePreview.Fill = ibsh;
            }
        }

        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
            this.Close();

            ModifingItem mi = new ModifingItem();

            Brush newForeground = tbForegroundSample.Foreground;
            Brush newBackground = rectanglePreview.Fill;
            Brush newSelbox1Brush = rect1.Stroke;
            Brush newSelBox2Brush = rect2.Stroke;

            if (newForeground != editor.DefaultForeground)
            {
                string newForegroundBrushName = ColorPicker.GetBrushName(newForeground);

                Action actForeground = new Action(null, -1, null, null,
                    ColorPicker.GetBrushName(editor.DefaultForeground),
                    newForegroundBrushName, ActionType.DefaultExForegroundChanging, null);

                editor.DefaultForeground = newForeground;
                mi.Add(actForeground);

                if (cbWithHeaderTextColor.IsChecked == true)
                {
                    Action actHeaderText1Color = new Action(null, -1, null, null,
                    ColorPicker.GetBrushName(Globals.selectedEditor.DefHeaderText1Brush),
                    newForegroundBrushName, ActionType.DefaultHeaderText1ColorChanging, null);

                    Globals.selectedEditor.DefHeaderText1Brush = newForeground;

                    Action actHeaderText2Color = new Action(null, -1, null, null,
                        ColorPicker.GetBrushName(Globals.selectedEditor.DefHeaderText2Brush),
                        newForegroundBrushName, ActionType.DefaultHeaderText2ColorChanging, null);

                    Globals.selectedEditor.DefHeaderText2Brush = newForeground;

                    Action actHeaderText3Color = new Action(null, -1, null, null,
                        ColorPicker.GetBrushName(Globals.selectedEditor.DefHeaderText3Brush),
                        newForegroundBrushName, ActionType.DefaultHeaderText3ColorChanging, null);

                    Globals.selectedEditor.DefHeaderText3Brush = newForeground;

                    Action actHeaderText4Color = new Action(null, -1, null, null,
                        ColorPicker.GetBrushName(Globals.selectedEditor.DefHeaderText4Brush),
                        newForegroundBrushName, ActionType.DefaultHeaderText4ColorChanging, null);

                    Globals.selectedEditor.DefHeaderText4Brush = newForeground;

                    mi.Add(actHeaderText1Color);
                    mi.Add(actHeaderText2Color);
                    mi.Add(actHeaderText3Color);
                    mi.Add(actHeaderText4Color);
                }
            }

            if (rbtnFillWithImageBrush.IsChecked == true)
            {
                if (newBackground != editor.DefaultBackground)
                {
                    string oldBrushValue = ColorPicker.GetBrushName(editor.DefaultBackground);

                    if (oldBrushValue == "UnKnow")
                    {
                        oldBrushValue = editor.XmlDocument.DocumentElement.GetAttributeByName("DefaultBackground").Value;
                    }

                    ImageBrush newImageBrush = rectanglePreview.Fill as ImageBrush;
                    ImageBrush oldImageBrush = editor.BaseScrolledViewer.Background as ImageBrush;

                    if (newImageBrush != null && oldImageBrush == null)//原本是纯色背景。
                    {
                        ImageBrush ib = newBackground as ImageBrush;
                        if (ib != null)
                        {
                            //将图片生成的base64文本写入editor。
                            string base64Str = tbxImageFilePath.Tag as string;
                            if (base64Str != null)
                            {
                                Action actBackground = new Action(null, -1, null, null,
                                    ColorPicker.GetBrushName(editor.DefaultBackground), base64Str,
                                    ActionType.DefaultExBackgroundChanging, null);

                                editor.DefaultBackground = ib;

                                editor.RootPanel.XmlData.SetAttribute("DefaultBackground", base64Str);

                                Action actTileMode = new Action(null, -1, null, null,
                                   (oldImageBrush == null ? null : oldImageBrush.TileMode.ToString()),
                                   ib.TileMode.ToString(), ActionType.TileMode, null);

                                editor.RootPanel.XmlData.SetAttribute("TileMode", ib.TileMode.ToString());

                                mi.Add(actBackground);
                                mi.Add(actTileMode);
                            }
                        }
                    }
                    else
                    {
                        if (newImageBrush != null && oldImageBrush != null)
                        {
                            if (newImageBrush.ImageSource != oldImageBrush.ImageSource)
                            {
                                ImageBrush ib = newBackground as ImageBrush;
                                if (ib != null)
                                {
                                    //将图片生成的base64文本写入editor。
                                    string base64Str = tbxImageFilePath.Tag as string;
                                    if (base64Str != null)
                                    {
                                        Action actBackground = new Action(null, -1, null, null,
                                            oldBrushValue, base64Str,
                                            ActionType.DefaultExBackgroundChanging, null);

                                        editor.DefaultBackground = ib;

                                        editor.RootPanel.XmlData.SetAttribute("DefaultBackground", base64Str);

                                        Action actTileMode = new Action(null, -1, null, null,
                                           (oldImageBrush == null ? null : oldImageBrush.TileMode.ToString()),
                                           ib.TileMode.ToString(), ActionType.TileMode, null);

                                        editor.RootPanel.XmlData.SetAttribute("TileMode", ib.TileMode.ToString());

                                        mi.Add(actBackground);
                                        mi.Add(actTileMode);
                                    }
                                }
                            }
                            else// if (newImageBrush.ImageSource == oldImageBrush.ImageSource)
                            {
                                //还有一种情况：只更改了“翻转”却没有更改图片。

                                //这种情况不需要将图片生成的base64文本写入editor。
                                Action actTileMode = new Action(null, -1, null, null,
                                    oldImageBrush.TileMode.ToString(), newImageBrush.TileMode.ToString(),
                                    ActionType.TileMode, null);

                                oldImageBrush.TileMode = newImageBrush.TileMode;

                                editor.RootPanel.XmlData.SetAttribute("TileMode", newImageBrush.TileMode.ToString());

                                mi.Add(actTileMode);
                            }
                        }
                    }
                }
            }
            else if (rbtnFillWithSolidBrush.IsChecked == true)
            {
                if (cboxBackgroundBrushes.SelectedIndex > 0)
                {
                    Brush newSolidBackBrush = rectanglePreview.Fill as SolidColorBrush;

                    if (newSolidBackBrush != null)
                    {
                        Action actBackground = new Action(null, -1, null, null,
                                editor.DefaultBackgroundXmlString,
                                ColorPicker.GetBrushName(newBackground),
                                ActionType.DefaultExBackgroundChanging, null);

                        editor.DefaultBackground = newSolidBackBrush;

                        ImageBrush iBshOld = editor.DefaultBackground as ImageBrush;
                        if (iBshOld != null)
                        {
                            Action actTileMode = new Action(null, -1, null, null,
                                iBshOld.TileMode.ToString(), null, ActionType.TileMode, null);

                            editor.XmlDocument.DocumentElement.SetAttribute("TileMode", "");
                        }

                        mi.Add(actBackground);
                    }
                }
            }

            if (newSelbox1Brush != editor.ExSelectionAdornerBrush)
            {
                Action actSelColor1 = new Action(null, -1, null, null,
                    ColorPicker.GetBrushName(editor.ExSelectionAdornerBrush),
                    ColorPicker.GetBrushName(newSelbox1Brush),
                    ActionType.ExSelectionAdornerBrushChanging, null);

                editor.ExSelectionAdornerBrush = newSelbox1Brush;
                mi.Add(actSelColor1);
            }

            if (newSelBox2Brush != editor.SubPanelSelectionAdornerBrush)
            {
                Action actSelColor2 = new Action(null, -1, null, null,
                    ColorPicker.GetBrushName(editor.SubPanelSelectionAdornerBrush),
                    ColorPicker.GetBrushName(newSelBox2Brush),
                    ActionType.SubPanelSelectionAdornerBrushChanging, null);

                editor.SubPanelSelectionAdornerBrush = newSelBox2Brush;
                mi.Add(actSelColor2);
            }

            editor.Do(mi);
            editor.IsModified = true;
        }
    }
}
